package configClient;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static configClient.ThreadSleepUtils.sleep;

/**
 * 生产 config client
 * 初始化 config client
 * 创建任务定时比较 configKey版本 并且拉取configKey
 */

public class ConfigClientManager {

    private static final ScheduledExecutorService scheduledThreadPool;
    private static final Random random;

    // 每隔十秒拉一次( 9s + 每台机器会随机休眠 0 - 1s 加起来就是 10s)
    private static final Integer RUN_INTERVAL = 9;
    // 延迟2秒后开始执行第一次
    private static final Integer INITIAL_DELAY = 2;

    static {
        random = new Random();
        // 创建ScheduledThreadPool，参数为线程池的大小
        scheduledThreadPool = Executors.newScheduledThreadPool(10);
    }

    public static ConfigClient createMysqlConfigCilent(String configKey,
                                                       String ip,
                                                       String port,
                                                       String username,
                                                       String password,
                                                       String dataBase,
                                                       String tableName
    ) {

        ConfigClient mysqlConfigClient = new MySqlConfigClient(
                configKey,
                ip,
                port,
                username,
                password,
                tableName,
                dataBase
        );

        // 初始化
        mysqlConfigClient.init();

        // 丢进定时任务线程池 (每隔 10s 执行一次)
        scheduledThreadPool.scheduleAtFixedRate(new PullTask(mysqlConfigClient), INITIAL_DELAY, RUN_INTERVAL, TimeUnit.SECONDS);

        return mysqlConfigClient;
    }

    public static class PullTask implements Runnable {

        private final ConfigClient configClient;

        public PullTask(ConfigClient configClient) {
            this.configClient = configClient;
        }

        @Override
        public void run() {

            // 首先判断是否发生改变
            if (configClient.configChange()) {
                // 重新拉取配置
                configClient.rePull();
            }

            // 随机休眠 (0, 1s) 错开不同单实例请求数据库，减少数据库。无任何业务语义
            long randomSleepTime = random.nextInt(1001);
            sleep(randomSleepTime, TimeUnit.MILLISECONDS);
        }
    }
}
